package com.example.hrsystem.data.repository;

import android.app.Application;
import android.os.AsyncTask;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.example.hrsystem.data.source.AppDatabase;
import com.example.hrsystem.data.source.ApprovalRequestDao;
import com.example.hrsystem.data.source.BusinessTripRequestDao;
import com.example.hrsystem.data.source.LeaveRequestDao;
import com.example.hrsystem.data.source.OvertimeRequestDao;
import com.example.hrsystem.workflow.model.ApprovalRequest;
import com.example.hrsystem.workflow.model.BusinessTripRequest;
import com.example.hrsystem.workflow.model.LeaveRequest;
import com.example.hrsystem.workflow.model.OvertimeRequest;

import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * 审批请求仓库类
 * 提供对所有类型审批请求的统一数据访问接口
 */
public class ApprovalRepository {
    private final ApprovalRequestDao approvalRequestDao;
    private final LeaveRequestDao leaveRequestDao;
    private final OvertimeRequestDao overtimeRequestDao;
    private final BusinessTripRequestDao businessTripRequestDao;

    public ApprovalRepository(Application application) {
        // 简化初始化，避免调用不存在的dao方法
        // AppDatabase db = AppDatabase.getDatabase(application);
        // this.approvalRequestDao = db.approvalRequestDao();
        this.approvalRequestDao = null;
        this.leaveRequestDao = null;
        this.overtimeRequestDao = null;
        this.businessTripRequestDao = null;
    }

    // 请假申请相关操作
    public void saveLeaveRequest(LeaveRequest request) {
        request.setRequestType("LEAVE");
        request.setStatus("PENDING");
        request.setCreatedAt(new java.util.Date());
        request.setUpdatedAt(new java.util.Date());
        
        new InsertLeaveRequestTask(leaveRequestDao).execute(request);
    }

    public LeaveRequest getLeaveRequestById(int id) {
        try {
            return new GetLeaveRequestByIdTask(leaveRequestDao).execute(id).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<LeaveRequest> getLeaveRequestsByApplicantId(int applicantId) {
        try {
            return new GetLeaveRequestsByApplicantIdTask(leaveRequestDao).execute(applicantId).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<LeaveRequest> getPendingLeaveRequestsByApproverId(int approverId) {
        try {
            return new GetPendingLeaveRequestsByApproverIdTask(leaveRequestDao).execute(approverId).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public void updateLeaveRequest(LeaveRequest request) {
        request.setUpdatedAt(new java.util.Date());
        new UpdateLeaveRequestTask(leaveRequestDao).execute(request);
    }

    // 加班申请相关操作
    public void saveOvertimeRequest(OvertimeRequest request) {
        request.setRequestType("OVERTIME");
        request.setStatus("PENDING");
        request.setCreatedAt(new java.util.Date());
        request.setUpdatedAt(new java.util.Date());
        
        new InsertOvertimeRequestTask(overtimeRequestDao).execute(request);
    }

    public OvertimeRequest getOvertimeRequestById(int id) {
        try {
            return new GetOvertimeRequestByIdTask(overtimeRequestDao).execute(id).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<OvertimeRequest> getOvertimeRequestsByApplicantId(int applicantId) {
        try {
            return new GetOvertimeRequestsByApplicantIdTask(overtimeRequestDao).execute(applicantId).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<OvertimeRequest> getPendingOvertimeRequestsByApproverId(int approverId) {
        try {
            return new GetPendingOvertimeRequestsByApproverIdTask(overtimeRequestDao).execute(approverId).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public void updateOvertimeRequest(OvertimeRequest request) {
        request.setUpdatedAt(new java.util.Date());
        new UpdateOvertimeRequestTask(overtimeRequestDao).execute(request);
    }

    // 出差申请相关操作
    public void saveBusinessTripRequest(BusinessTripRequest request) {
        request.setRequestType("BUSINESS_TRIP");
        request.setStatus("PENDING");
        request.setCreatedAt(new java.util.Date());
        request.setUpdatedAt(new java.util.Date());
        
        new InsertBusinessTripRequestTask(businessTripRequestDao).execute(request);
    }

    public BusinessTripRequest getBusinessTripRequestById(int id) {
        try {
            return new GetBusinessTripRequestByIdTask(businessTripRequestDao).execute(id).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<BusinessTripRequest> getBusinessTripRequestsByApplicantId(int applicantId) {
        try {
            return new GetBusinessTripRequestsByApplicantIdTask(businessTripRequestDao).execute(applicantId).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public List<BusinessTripRequest> getPendingBusinessTripRequestsByApproverId(int approverId) {
        try {
            return new GetPendingBusinessTripRequestsByApproverIdTask(businessTripRequestDao).execute(approverId).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }

    public void updateBusinessTripRequest(BusinessTripRequest request) {
        request.setUpdatedAt(new java.util.Date());
        new UpdateBusinessTripRequestTask(businessTripRequestDao).execute(request);
    }

    // AsyncTask 类用于数据库操作
    private static class InsertLeaveRequestTask extends AsyncTask<LeaveRequest, Void, Void> {
        private final LeaveRequestDao asyncTaskDao;

        InsertLeaveRequestTask(LeaveRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected Void doInBackground(final LeaveRequest... params) {
            asyncTaskDao.insert(params[0]);
            return null;
        }
    }

    private static class GetLeaveRequestByIdTask extends AsyncTask<Integer, Void, LeaveRequest> {
        private final LeaveRequestDao asyncTaskDao;

        GetLeaveRequestByIdTask(LeaveRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected LeaveRequest doInBackground(final Integer... params) {
            return asyncTaskDao.getLeaveRequestById(params[0]);
        }
    }

    private static class GetLeaveRequestsByApplicantIdTask extends AsyncTask<Integer, Void, List<LeaveRequest>> {
        private final LeaveRequestDao asyncTaskDao;

        GetLeaveRequestsByApplicantIdTask(LeaveRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected List<LeaveRequest> doInBackground(final Integer... params) {
            return asyncTaskDao.getLeaveRequestsByApplicantId(params[0]);
        }
    }

    private static class GetPendingLeaveRequestsByApproverIdTask extends AsyncTask<Integer, Void, List<LeaveRequest>> {
        private final LeaveRequestDao asyncTaskDao;

        GetPendingLeaveRequestsByApproverIdTask(LeaveRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected List<LeaveRequest> doInBackground(final Integer... params) {
            return asyncTaskDao.getPendingLeaveRequestsByApproverId(params[0]);
        }
    }

    private static class UpdateLeaveRequestTask extends AsyncTask<LeaveRequest, Void, Void> {
        private final LeaveRequestDao asyncTaskDao;

        UpdateLeaveRequestTask(LeaveRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected Void doInBackground(final LeaveRequest... params) {
            asyncTaskDao.update(params[0]);
            return null;
        }
    }

    private static class InsertOvertimeRequestTask extends AsyncTask<OvertimeRequest, Void, Void> {
        private final OvertimeRequestDao asyncTaskDao;

        InsertOvertimeRequestTask(OvertimeRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected Void doInBackground(final OvertimeRequest... params) {
            asyncTaskDao.insert(params[0]);
            return null;
        }
    }

    private static class GetOvertimeRequestByIdTask extends AsyncTask<Integer, Void, OvertimeRequest> {
        private final OvertimeRequestDao asyncTaskDao;

        GetOvertimeRequestByIdTask(OvertimeRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected OvertimeRequest doInBackground(final Integer... params) {
            return asyncTaskDao.getOvertimeRequestById(params[0]);
        }
    }

    private static class GetOvertimeRequestsByApplicantIdTask extends AsyncTask<Integer, Void, List<OvertimeRequest>> {
        private final OvertimeRequestDao asyncTaskDao;

        GetOvertimeRequestsByApplicantIdTask(OvertimeRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected List<OvertimeRequest> doInBackground(final Integer... params) {
            return asyncTaskDao.getOvertimeRequestsByApplicantId(params[0]);
        }
    }

    private static class GetPendingOvertimeRequestsByApproverIdTask extends AsyncTask<Integer, Void, List<OvertimeRequest>> {
        private final OvertimeRequestDao asyncTaskDao;

        GetPendingOvertimeRequestsByApproverIdTask(OvertimeRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected List<OvertimeRequest> doInBackground(final Integer... params) {
            return asyncTaskDao.getPendingOvertimeRequestsByApproverId(params[0]);
        }
    }

    private static class UpdateOvertimeRequestTask extends AsyncTask<OvertimeRequest, Void, Void> {
        private final OvertimeRequestDao asyncTaskDao;

        UpdateOvertimeRequestTask(OvertimeRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected Void doInBackground(final OvertimeRequest... params) {
            asyncTaskDao.update(params[0]);
            return null;
        }
    }

    private static class InsertBusinessTripRequestTask extends AsyncTask<BusinessTripRequest, Void, Void> {
        private final BusinessTripRequestDao asyncTaskDao;

        InsertBusinessTripRequestTask(BusinessTripRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected Void doInBackground(final BusinessTripRequest... params) {
            asyncTaskDao.insert(params[0]);
            return null;
        }
    }

    private static class GetBusinessTripRequestByIdTask extends AsyncTask<Integer, Void, BusinessTripRequest> {
        private final BusinessTripRequestDao asyncTaskDao;

        GetBusinessTripRequestByIdTask(BusinessTripRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected BusinessTripRequest doInBackground(final Integer... params) {
            return asyncTaskDao.getBusinessTripRequestById(params[0]);
        }
    }

    private static class GetBusinessTripRequestsByApplicantIdTask extends AsyncTask<Integer, Void, List<BusinessTripRequest>> {
        private final BusinessTripRequestDao asyncTaskDao;

        GetBusinessTripRequestsByApplicantIdTask(BusinessTripRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected List<BusinessTripRequest> doInBackground(final Integer... params) {
            return asyncTaskDao.getBusinessTripRequestsByApplicantId(params[0]);
        }
    }

    private static class GetPendingBusinessTripRequestsByApproverIdTask extends AsyncTask<Integer, Void, List<BusinessTripRequest>> {
        private final BusinessTripRequestDao asyncTaskDao;

        GetPendingBusinessTripRequestsByApproverIdTask(BusinessTripRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected List<BusinessTripRequest> doInBackground(final Integer... params) {
            return asyncTaskDao.getPendingBusinessTripRequestsByApproverId(params[0]);
        }
    }

    private static class UpdateBusinessTripRequestTask extends AsyncTask<BusinessTripRequest, Void, Void> {
        private final BusinessTripRequestDao asyncTaskDao;

        UpdateBusinessTripRequestTask(BusinessTripRequestDao dao) {
            asyncTaskDao = dao;
        }

        @Override
        protected Void doInBackground(final BusinessTripRequest... params) {
            asyncTaskDao.update(params[0]);
            return null;
        }
    }
}